{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Working with tabular data: Pandas\n",
"\n",
"Pandas provides three things: \n",
"1. a new data type specifically designed for tabular data - the `DataFrame`\n",
"2. functions for manipulating tabular data\n",
"3. IO for tabular data (covered in Week3/Files)\n",
"\n",
"## Why yet another data type?\n",
"Numpy arrays can hold tabular data - 2D matrices. So why do we need another, special data type?\n",
"One problem with raw 2D arrays is that they are not self-documenting. What does that mean?\n",
"\n",
"Take the data from exercise of Week3/Files: We calculated behavioral scores, stored them in a numpy array, and saved the array to a text file:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.08656877, 0.26186048],\n",
" [0.27081788, 0.48948194],\n",
" [0.47072199, 0.65700287],\n",
" [0.55996639, 0.81680243],\n",
" [0.84880959, 0.98686545],\n",
" [0.91045131, 0.99465925]])"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"# load and print matrix\n",
"scores = np.loadtxt('dat/pd_scores.txt')\n",
"scores"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Do you remember what the data means? What are the individual rows? What are the columns? Imagine this were an analysis on your own data and you'd want to look at the results in 3 months or so.\n",
"\n",
"There are no labels, so it's hard to know from the data itself what they mean - the data is not \"self-documenting\"\n",
"\n",
"We can turn this into a DataFrame:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
intial score
\n",
"
final score
\n",
"
\n",
" \n",
" \n",
"
\n",
"
20230912
\n",
"
0.086569
\n",
"
0.261860
\n",
"
\n",
"
\n",
"
20230913
\n",
"
0.270818
\n",
"
0.489482
\n",
"
\n",
"
\n",
"
20230914
\n",
"
0.470722
\n",
"
0.657003
\n",
"
\n",
"
\n",
"
20230915
\n",
"
0.559966
\n",
"
0.816802
\n",
"
\n",
"
\n",
"
20230916
\n",
"
0.848810
\n",
"
0.986865
\n",
"
\n",
"
\n",
"
20230917
\n",
"
0.910451
\n",
"
0.994659
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" intial score final score\n",
"20230912 0.086569 0.261860\n",
"20230913 0.270818 0.489482\n",
"20230914 0.470722 0.657003\n",
"20230915 0.559966 0.816802\n",
"20230916 0.848810 0.986865\n",
"20230917 0.910451 0.994659"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"\n",
"# the folder names correspond to the days\n",
"days = ['20230912','20230913','20230914','20230915','20230916','20230917']\n",
"\n",
"# make DataFrame - no need to understand the specifics - I will explain soon what is going on here\n",
"# we can easily turn a dictionary into a DataFrame - keys will be column labels, values are the per-row data\n",
"# we can also specify row labels - an index.\n",
"scores_dict = {'intial score': scores[:, 0], 'final score': scores[:, 1]}\n",
"df = pd.DataFrame(scores_dict, index=days)\n",
"df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can save the data frame as csv and excel, and reload them as a DataFrame, with the labels being preserved:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Unnamed: 0
\n",
"
final score
\n",
"
\n",
"
\n",
"
intial score
\n",
"
\n",
"
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0.086569
\n",
"
20230912
\n",
"
0.261860
\n",
"
\n",
"
\n",
"
0.270818
\n",
"
20230913
\n",
"
0.489482
\n",
"
\n",
"
\n",
"
0.470722
\n",
"
20230914
\n",
"
0.657003
\n",
"
\n",
"
\n",
"
0.559966
\n",
"
20230915
\n",
"
0.816802
\n",
"
\n",
"
\n",
"
0.848810
\n",
"
20230916
\n",
"
0.986865
\n",
"
\n",
"
\n",
"
0.910451
\n",
"
20230917
\n",
"
0.994659
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Unnamed: 0 final score\n",
"intial score \n",
"0.086569 20230912 0.261860\n",
"0.270818 20230913 0.489482\n",
"0.470722 20230914 0.657003\n",
"0.559966 20230915 0.816802\n",
"0.848810 20230916 0.986865\n",
"0.910451 20230917 0.994659"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.to_csv('dat/scores_df.csv')\n",
"df.to_excel('dat/scores_df.xlsx')\n",
"\n",
"# load data\n",
"df_from_file = pd.read_csv('dat/scores_df.csv', index_col=0, )\n",
"df_from_file"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating DataFrames\n",
"\n",
"We already learned that pandas provides versatile file I/O (csv, excel): [https://pandas.pydata.org/docs/user_guide/io.html]() (see Week3/Files)\n",
"\n",
"As shown above, a DataFrame can be created from Dictionary.\n",
"\n",
"Data is 2D and is organized in columns and rows (rows=index). If we do not specify an index during DataFrame creation, it will be generated automatically, as a row numbers:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'column 1': ['a', 'b', 'c'], 'column 2': [10, 20, 30]}\n"
]
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
column 1
\n",
"
column 2
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
a
\n",
"
10
\n",
"
\n",
"
\n",
"
1
\n",
"
b
\n",
"
20
\n",
"
\n",
"
\n",
"
2
\n",
"
c
\n",
"
30
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" column 1 column 2\n",
"0 a 10\n",
"1 b 20\n",
"2 c 30"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"d = {'column 1': ['a','b','c'], 'column 2': [10, 20, 30]}\n",
"\n",
"print(d)\n",
"df = pd.DataFrame(d)\n",
"df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A DataFrame can also be created from a 2D np.array. In that case, we can specify the column names separately:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['20230912', '20230913', '20230914', '20230915', '20230916', '20230917']"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# scores\n",
"days"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
initial
\n",
"
final
\n",
"
\n",
" \n",
" \n",
"
\n",
"
20230912
\n",
"
0.086569
\n",
"
0.261860
\n",
"
\n",
"
\n",
"
20230913
\n",
"
0.270818
\n",
"
0.489482
\n",
"
\n",
"
\n",
"
20230914
\n",
"
0.470722
\n",
"
0.657003
\n",
"
\n",
"
\n",
"
20230915
\n",
"
0.559966
\n",
"
0.816802
\n",
"
\n",
"
\n",
"
20230916
\n",
"
0.848810
\n",
"
0.986865
\n",
"
\n",
"
\n",
"
20230917
\n",
"
0.910451
\n",
"
0.994659
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" initial final\n",
"20230912 0.086569 0.261860\n",
"20230913 0.270818 0.489482\n",
"20230914 0.470722 0.657003\n",
"20230915 0.559966 0.816802\n",
"20230916 0.848810 0.986865\n",
"20230917 0.910451 0.994659"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.DataFrame(scores, columns=['initial', 'final'], index=days)\n",
"df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Accessing data in DataFrames\n",
"There are many ways of accessing data in a DataFrame. We cover the basics here.\n",
"\n",
"More details: [https://pandas.pydata.org/docs/user_guide/indexing.html]()\n",
"\n",
"### Access columns like a dictionary"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"20230912 0.261860\n",
"20230913 0.489482\n",
"20230914 0.657003\n",
"20230915 0.816802\n",
"20230916 0.986865\n",
"20230917 0.994659\n",
"Name: final, dtype: float64"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df['final'] # df[column_name]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Access rows and columns by name like a 2D dictionary via df.loc\n",
"\n",
"`df.loc[index_name, column_name]`"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
initial
\n",
"
final
\n",
"
\n",
" \n",
" \n",
"
\n",
"
20230912
\n",
"
0.086569
\n",
"
0.261860
\n",
"
\n",
"
\n",
"
20230913
\n",
"
0.270818
\n",
"
0.489482
\n",
"
\n",
"
\n",
"
20230914
\n",
"
0.470722
\n",
"
0.657003
\n",
"
\n",
"
\n",
"
20230915
\n",
"
0.559966
\n",
"
0.816802
\n",
"
\n",
"
\n",
"
20230916
\n",
"
0.848810
\n",
"
0.986865
\n",
"
\n",
"
\n",
"
20230917
\n",
"
0.910451
\n",
"
0.994659
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" initial final\n",
"20230912 0.086569 0.261860\n",
"20230913 0.270818 0.489482\n",
"20230914 0.470722 0.657003\n",
"20230915 0.559966 0.816802\n",
"20230916 0.848810 0.986865\n",
"20230917 0.910451 0.994659"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"20230912 0.086569\n",
"20230913 0.270818\n",
"20230914 0.470722\n",
"20230915 0.559966\n",
"20230916 0.848810\n",
"20230917 0.910451\n",
"Name: initial, dtype: float64"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.DataFrame(scores, columns=['initial', 'final'], index=days)\n",
"display(df)\n",
"\n",
"df.loc[:, 'initial']\n",
"\n",
"\n",
"# print(\"by row name - all columns: df.loc['20230915']\")\n",
"# print(df.loc['20230915'])\n",
"\n",
"# print(\"this is equivalent to: df.loc['20230915', :]\")\n",
"# print(df.loc['20230915', :])\n",
"\n",
"# print(\"by column name - all rows, one column: df.loc[:, 'initial']\")\n",
"# print(df.loc[:, 'initial'])\n",
"\n",
"# print(\"\\nby row and column name - returns a single cell in the table: df.loc['20230915', 'initial']\")\n",
"# print(df.loc['20230915', 'initial'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Access to rows and columns via a numerical index like a 2D array via df.iloc\n",
"\n",
"`df.iloc[row_number, column_number]`"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"20230912 0.261860\n",
"20230913 0.489482\n",
"20230914 0.657003\n",
"20230915 0.816802\n",
"20230916 0.986865\n",
"20230917 0.994659\n",
"Name: final, dtype: float64\n",
"initial 0.270818\n",
"final 0.489482\n",
"Name: 20230913, dtype: float64\n",
"initial 0.270818\n",
"final 0.489482\n",
"Name: 20230913, dtype: float64\n",
"0.6570028706902653\n",
"20230912 0.261860\n",
"20230913 0.489482\n",
"Name: final, dtype: float64\n"
]
}
],
"source": [
"print(df.iloc[:, 1])\n",
"print(df.iloc[1])\n",
"print(df.iloc[1, :])\n",
"print(df.iloc[2, 1])\n",
"print(df.iloc[:2, 1]) # slicing also works"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Mini-Exercise:\n",
"Get from the DataFrame below:\n",
"- all data from the 'test' column\n",
"- all data from the '...' row\n",
"- data from the cell at row '...' and column '...'\n",
"- the data from the 5th row"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df = pd.DataFrame(...)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Access the underlying data like a numpy array:"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([[0.08656877, 0.26186048],\n",
" [0.27081788, 0.48948194],\n",
" [0.47072199, 0.65700287],\n",
" [0.55996639, 0.81680243],\n",
" [0.84880959, 0.98686545],\n",
" [0.91045131, 0.99465925]]),\n",
" numpy.ndarray)"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = df.values\n",
"data, type(data)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Boolean indexing also works"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
"
],
"text/plain": [
" name age score\n",
"0 Tim 12 4\n",
"1 Jim 24 0\n",
"2 Pim 18 8\n",
"3 Pip 22 9\n",
"4 Tom 26 7"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
name
\n",
"
age
\n",
"
score
\n",
"
\n",
" \n",
" \n",
"
\n",
"
1
\n",
"
Jim
\n",
"
24
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
Pip
\n",
"
22
\n",
"
9
\n",
"
\n",
"
\n",
"
4
\n",
"
Tom
\n",
"
26
\n",
"
7
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" name age score\n",
"1 Jim 24 0\n",
"3 Pip 22 9\n",
"4 Tom 26 7"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
name
\n",
"
age
\n",
"
score
\n",
"
\n",
" \n",
" \n",
"
\n",
"
3
\n",
"
Pip
\n",
"
22
\n",
"
9
\n",
"
\n",
"
\n",
"
4
\n",
"
Tom
\n",
"
26
\n",
"
7
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" name age score\n",
"3 Pip 22 9\n",
"4 Tom 26 7"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"df = pd.DataFrame({'name': ['Tim', 'Jim', 'Pim', 'Pip', 'Tom'],\n",
" 'age': [12, 24, 18, 22, 26],\n",
" 'score': [4, 0, 8, 9, 7]})\n",
"display(df)\n",
"\n",
"# first, keep only the old one - age>20 yrs\n",
"old_guys = df[df['age']> 20]\n",
"display(old_guys)\n",
"\n",
"# then, filter the dataframe with the old ones, to keep only the high scores - score>4\n",
"high_scorer = old_guys[old_guys['score']> 4]\n",
"display(high_scorer)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Groupby: Split-apply-combine\n",
"A common problem in data analysis is:\n",
"\n",
"We have an experiment with multiple subjects, and multiple measurements per subject. We'd like to compute the average score for each subject for plotting and statistics.\n",
"\n",
"For instance:"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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I4GFEEIIIfymywQWr7zyCgMGDCA0NJQJEyawatWqQC+pQ1i5ciXnn38+KSkpGAwGPv/88wbXa5rGo48+SkpKCmFhYcycOZPt27cHZrEdwPz585k0aRJRUVEkJiZy0UUXsXv37ga3keesoQULFjB69Gh7w52pU6eyePFi+/XyfHk2f/58DAYDc+fOtV8mz5nDo48+isFgaPAnKSnJfr08V65lZ2dz3XXXER8fT3h4OGPHjmXjxo3269vyeesSgcWHH37I3LlzeeCBB9i8eTMnnXQSZ599NkeOHAn00gKuoqKCMWPG8NJLL7m8/m9/+xvPPvssL730EuvXrycpKYlZs2bZZ7p0NytWrOD2229n3bp1LFmyhPr6embPnk1FRYX9NvKcNdSnTx+efvppNmzYwIYNGzjttNO48MIL7S9S8ny5t379el577TVGjx7d4HJ5zhoaOXIkR48etf/JyMiwXyfPVVPFxcVMnz6doKAgFi9ezI4dO/jnP/9JbGys/TZt+rxpXcDkyZO1W2+9tcFlw4YN0+69994ArahjArTPPvvM/ner1aolJSVpTz/9tP2y6upqLSYmRnv11VcDsMKOJz8/XwO0FStWaJomz5m3evToob3xxhvyfHlQVlamDRkyRFuyZIl2yimnaHPmzNE0Tf6NNfbII49oY8aMcXmdPFeu3XPPPdqMGTPcXt/Wz1un37Gora1l48aNzJ49u8Hls2fPZs2aNQFaVedw8OBBcnNzGzx3ISEhnHLKKfLc2ZSUlAAQFxcHyHPWHIvFwgcffEBFRQVTp06V58uD22+/nXPPPZczzjijweXynDW1d+9eUlJSGDBgAFdddRUHDhwA5Lly58svv2TixIlcfvnlJCYmMm7cOF5//XX79W39vHX6wKKgoACLxUKvXr0aXN6rVy9yc3MDtKrOQX9+5LlzTdM05s2bx4wZMxg1ahQgz5k7GRkZREZGEhISwq233spnn33GiBEj5Ply44MPPmDTpk3Mnz+/yXXynDU0ZcoU3n77bb7//ntef/11cnNzmTZtGoWFhfJcuXHgwAEWLFjAkCFD+P7777n11lu56667ePvtt4G2/zfW7tNN20rjEeyapvl1LHtXJs+da3fccQfp6en8/PPPTa6T56yhE044gS1btnD8+HE++eQTbrjhBlasWGG/Xp4vh8zMTObMmcMPP/xAaGio29vJc6acffbZ9u/T0tKYOnUqgwYN4q233uLEE08E5LlqzGq1MnHiRJ566ikAxo0bx/bt21mwYAG/+c1v7Ldrq+et0+9YJCQkYDKZmkRZ+fn5TaIx0ZCeWS3PXVN33nknX375JcuWLaNPnz72y+U5cy04OJjBgwczceJE5s+fz5gxY/jXv/4lz5cLGzduJD8/nwkTJmA2mzGbzaxYsYIXXngBs9lsf17kOXMtIiKCtLQ09u7dK/++3EhOTmbEiBENLhs+fLi9oKGtn7dOH1gEBwczYcIElixZ0uDyJUuWMG3atACtqnMYMGAASUlJDZ672tpaVqxY0W2fO03TuOOOO/j000/56aefGDBgQIPr5TnzjqZp1NTUyPPlwumnn05GRgZbtmyx/5k4cSLXXnstW7ZsYeDAgfKceVBTU8POnTtJTk6Wf19uTJ8+vUmZ/J49e+jXrx/QDq9jrU7/7AA++OADLSgoSHvzzTe1HTt2aHPnztUiIiK0Q4cOBXppAVdWVqZt3rxZ27x5swZozz77rLZ582bt8OHDmqZp2tNPP63FxMRon376qZaRkaFdffXVWnJyslZaWhrglQfGH//4Ry0mJkZbvny5dvToUfufyspK+23kOWvovvvu01auXKkdPHhQS09P1+6//37NaDRqP/zwg6Zp8nx5w7kqRNPkOXP25z//WVu+fLl24MABbd26ddp5552nRUVF2V/f5blq6tdff9XMZrP25JNPanv37tXeffddLTw8XFu0aJH9Nm35vHWJwELTNO3ll1/W+vXrpwUHB2vjx4+3lwd2d8uWLdOAJn9uuOEGTdNU2dEjjzyiJSUlaSEhIdrJJ5+sZWRkBHbRAeTquQK0hQsX2m8jz1lDv/vd7+y/ez179tROP/10e1ChafJ8eaNxYCHPmcOVV16pJScna0FBQVpKSop2ySWXaNu3b7dfL8+Va1999ZU2atQoLSQkRBs2bJj22muvNbi+LZ83GZsuhBBCCL/p9DkWQgghhOg4JLAQQgghhN9IYCGEEEIIv5HAQgghhBB+I4GFEEIIIfxGAgshhBBC+I0EFkIIIYTwGwkshBBCCOE3ElgIIYQQwm8ksBBCCCGE30hgIYQQQgi/kcBCCCGEEH7z/5tFExzm4JN0AAAAAElFTkSuQmCC",
"text/plain": [
"
"
],
"text/plain": [
" animal pre post\n",
"0 0.0 2.211986 3.107796\n",
"1 0.0 2.204871 2.830730\n",
"2 0.0 2.560633 3.483980\n",
"3 0.0 1.476412 2.801709\n",
"4 0.0 3.662519 3.447005\n",
"5 0.0 2.538696 3.301515"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"animal 0.000000\n",
"pre 2.442519\n",
"post 3.162122\n",
"dtype: float64"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"animal 0.000000\n",
"pre 2.442519\n",
"post 3.162122\n",
"dtype: float64"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"[array([0. , 2.44251943, 3.16212242]),\n",
" array([1. , 2.73811958, 3.01536034]),\n",
" array([2. , 3.36372726, 3.62369364]),\n",
" array([3. , 2.32101921, 2.82037202]),\n",
" array([4. , 2.03732544, 2.14435453]),\n",
" array([5. , 1.98184125, 3.0878241 ]),\n",
" array([6. , 1.35130571, 1.55273191]),\n",
" array([7. , 3.08961177, 3.51681884]),\n",
" array([8. , 2.09822498, 2.79135462]),\n",
" array([9. , 1.9379714 , 2.03333186])]"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# identify all animals\n",
"animals = df['animal'].unique()\n",
"\n",
"# example of boolean indexing\n",
"display(df[df['animal']==0.0])\n",
"# compute the mean:\n",
"display(df[df['animal']==0.0].mean())\n",
"display(np.mean(df[df['animal']==0.0], axis=0))\n",
"\n",
"# loop over all animals\n",
"animal_avg = []\n",
"for animal in animals:\n",
" animal_avg.append(df[df['animal']==animal].mean().values)\n",
"animal_avg\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This series of steps is so common, that it has been implemented in pandas: [https://pandas.pydata.org/docs/user_guide/groupby.html]()\n",
"\n",
"It is applied in two steps: _groupby_ and _aggregate_\n",
"1. _groupby_ groups the rows that have the same value in a specific column together\n",
"2. _aggregate_ applies a computation that aggregates all data in a group to a single number, like the mean, standard deviation, or max.\n",
"\n",
"Here is an example of this in action. `df.groupby(column_name)` will produce a new object, that groups all rows with the same value in the specified column into a \"virtual subtable\":"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
animal
\n",
"
pre
\n",
"
post
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
0.0
\n",
"
2.211986
\n",
"
3.107796
\n",
"
\n",
"
\n",
"
1
\n",
"
0.0
\n",
"
2.204871
\n",
"
2.830730
\n",
"
\n",
"
\n",
"
2
\n",
"
0.0
\n",
"
2.560633
\n",
"
3.483980
\n",
"
\n",
"
\n",
"
3
\n",
"
0.0
\n",
"
1.476412
\n",
"
2.801709
\n",
"
\n",
"
\n",
"
4
\n",
"
0.0
\n",
"
3.662519
\n",
"
3.447005
\n",
"
\n",
"
\n",
"
5
\n",
"
0.0
\n",
"
2.538696
\n",
"
3.301515
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" animal pre post\n",
"0 0.0 2.211986 3.107796\n",
"1 0.0 2.204871 2.830730\n",
"2 0.0 2.560633 3.483980\n",
"3 0.0 1.476412 2.801709\n",
"4 0.0 3.662519 3.447005\n",
"5 0.0 2.538696 3.301515"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"grouped = df.groupby('animal')\n",
"print(type(grouped))\n",
"grouped.get_group(0) # get the subtable for all rows where animal==0.0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Apply the \"mean\" operation to all values in each subtable and make a new table with the aggregate per-group data:"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/var/folders/zr/6ql4dzjx0tq8mpzht_2dwh480000gn/T/ipykernel_3584/1479352327.py:1: FutureWarning: The provided callable is currently using DataFrameGroupBy.mean. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"mean\" instead.\n",
" agg = grouped.aggregate(np.mean)\n"
]
},
{
"data": {
"text/html": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"x = np.zeros_like(agg.values).T + [[0], [1]]\n",
"y = agg.values.T\n",
"\n",
"plt.figure(figsize=(3, 6))\n",
"plt.plot(x, y, 'o-k')\n",
"plt.xticks([0, 1], labels=agg.columns)\n",
"plt.ylabel('Score')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: Connectomics\n",
"The connectome of the (female) fly brain was recently published.\n",
"\n",
"It can be accessed usign a beautiful web interface and user friendly web site: [https://codex.flywire.ai]().\n",
"\n",
"The web site is great for exploring the fly brain, but clicking around in a web browser has limitations in terms of the reproducibility and scale of an analysis.\n",
"\n",
"Therefore, the data was made availabel as a set of tables that can be loaded and processed with pandas.\n",
"\n",
"In the exercise, we will use pandas to answer neuroscience questions about the fly brain - here is a brief introduction to the data:\n",
"\n",
"There are three main tables:\n",
"- connections - connections between cells\n",
"- classification - cell classes (afferent, intrinsic, efferent), ...\n",
"- (labels - human annotations of cell types)\n",
"\n",
"Each neuron has a unique identifier, the root_id. The root_id can be used to track neurons across the different tables.\n",
"For instance, to find all neurons of a specific types, and then find their inputs or outputs."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Classifications and connections\n",
"The classification table has basic information about each of the 130k neurons in the fly brain: the cell_type, side of the brain, position in the brain etc."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
root_id
\n",
"
flow
\n",
"
super_class
\n",
"
class
\n",
"
sub_class
\n",
"
cell_type
\n",
"
hemibrain_type
\n",
"
hemilineage
\n",
"
side
\n",
"
nerve
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
720575940627005443
\n",
"
intrinsic
\n",
"
optic
\n",
"
L1-5
\n",
"
NaN
\n",
"
L4
\n",
"
NaN
\n",
"
NaN
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
1
\n",
"
720575940615995398
\n",
"
intrinsic
\n",
"
optic
\n",
"
L1-5
\n",
"
NaN
\n",
"
L4
\n",
"
NaN
\n",
"
NaN
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
2
\n",
"
720575940621762567
\n",
"
afferent
\n",
"
ascending
\n",
"
AN
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
right
\n",
"
CV
\n",
"
\n",
"
\n",
"
3
\n",
"
720575940624384007
\n",
"
afferent
\n",
"
sensory
\n",
"
olfactory
\n",
"
NaN
\n",
"
NaN
\n",
"
ORN_VA1v
\n",
"
NaN
\n",
"
left
\n",
"
AN
\n",
"
\n",
"
\n",
"
4
\n",
"
720575940614422540
\n",
"
intrinsic
\n",
"
central
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
AOTU032,AOTU034
\n",
"
LALa1_posterior
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
127974
\n",
"
720575940621500404
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
LLPC1,LLPC2a,LLPC2b,LLPC2c,LLPC2d,LLPC3
\n",
"
NaN
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
127975
\n",
"
720575940651646966
\n",
"
intrinsic
\n",
"
central
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
LB0_anterior
\n",
"
center
\n",
"
NaN
\n",
"
\n",
"
\n",
"
127976
\n",
"
720575940630151162
\n",
"
intrinsic
\n",
"
optic
\n",
"
optic_lobes
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
127977
\n",
"
720575940629364731
\n",
"
intrinsic
\n",
"
optic
\n",
"
optic_lobes
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
NaN
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
127978
\n",
"
720575940623859711
\n",
"
afferent
\n",
"
sensory
\n",
"
visual
\n",
"
NaN
\n",
"
R1-6
\n",
"
NaN
\n",
"
NaN
\n",
"
right
\n",
"
NaN
\n",
"
\n",
" \n",
"
\n",
"
127979 rows × 10 columns
\n",
"
"
],
"text/plain": [
" root_id flow super_class class \\\n",
"0 720575940627005443 intrinsic optic L1-5 \n",
"1 720575940615995398 intrinsic optic L1-5 \n",
"2 720575940621762567 afferent ascending AN \n",
"3 720575940624384007 afferent sensory olfactory \n",
"4 720575940614422540 intrinsic central NaN \n",
"... ... ... ... ... \n",
"127974 720575940621500404 intrinsic visual_projection NaN \n",
"127975 720575940651646966 intrinsic central NaN \n",
"127976 720575940630151162 intrinsic optic optic_lobes \n",
"127977 720575940629364731 intrinsic optic optic_lobes \n",
"127978 720575940623859711 afferent sensory visual \n",
"\n",
" sub_class cell_type hemibrain_type \\\n",
"0 NaN L4 NaN \n",
"1 NaN L4 NaN \n",
"2 NaN NaN NaN \n",
"3 NaN NaN ORN_VA1v \n",
"4 NaN NaN AOTU032,AOTU034 \n",
"... ... ... ... \n",
"127974 NaN NaN LLPC1,LLPC2a,LLPC2b,LLPC2c,LLPC2d,LLPC3 \n",
"127975 NaN NaN NaN \n",
"127976 NaN NaN NaN \n",
"127977 NaN NaN NaN \n",
"127978 NaN R1-6 NaN \n",
"\n",
" hemilineage side nerve \n",
"0 NaN right NaN \n",
"1 NaN right NaN \n",
"2 NaN right CV \n",
"3 NaN left AN \n",
"4 LALa1_posterior right NaN \n",
"... ... ... ... \n",
"127974 NaN right NaN \n",
"127975 LB0_anterior center NaN \n",
"127976 NaN left NaN \n",
"127977 NaN right NaN \n",
"127978 NaN right NaN \n",
"\n",
"[127979 rows x 10 columns]"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"classification = pd.read_csv('dat/flywire/classification.csv.gz')\n",
"classification"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The connections table contains information about all ~4M synaptic synaptic connections:\n",
"- pre_root_id: root_id of the presynaptic neuron, the source\n",
"- post_root_id: root_id of the postsynaptic neuron, the target\n",
"- syn_count: number of synapses in connection\n",
"- nt_type: predicted neurotransmitter neurotransmitter \n",
"- neuropil: target neuropil"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
pre_root_id
\n",
"
post_root_id
\n",
"
neuropil
\n",
"
syn_count
\n",
"
nt_type
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
720575940596125868
\n",
"
720575940608552405
\n",
"
LOP_R
\n",
"
5
\n",
"
ACH
\n",
"
\n",
"
\n",
"
1
\n",
"
720575940596125868
\n",
"
720575940611348834
\n",
"
LOP_R
\n",
"
7
\n",
"
ACH
\n",
"
\n",
"
\n",
"
2
\n",
"
720575940596125868
\n",
"
720575940613059993
\n",
"
LOP_R
\n",
"
5
\n",
"
GLUT
\n",
"
\n",
"
\n",
"
3
\n",
"
720575940596125868
\n",
"
720575940616986553
\n",
"
LOP_R
\n",
"
5
\n",
"
ACH
\n",
"
\n",
"
\n",
"
4
\n",
"
720575940596125868
\n",
"
720575940620124326
\n",
"
LOP_R
\n",
"
8
\n",
"
ACH
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
3794610
\n",
"
720575940660868737
\n",
"
720575940607206786
\n",
"
ME_L
\n",
"
9
\n",
"
GABA
\n",
"
\n",
"
\n",
"
3794611
\n",
"
720575940660868737
\n",
"
720575940608664873
\n",
"
ME_L
\n",
"
6
\n",
"
GABA
\n",
"
\n",
"
\n",
"
3794612
\n",
"
720575940660868737
\n",
"
720575940611462242
\n",
"
ME_L
\n",
"
6
\n",
"
GABA
\n",
"
\n",
"
\n",
"
3794613
\n",
"
720575940660868737
\n",
"
720575940622913063
\n",
"
ME_L
\n",
"
23
\n",
"
GABA
\n",
"
\n",
"
\n",
"
3794614
\n",
"
720575940660868737
\n",
"
720575940626553546
\n",
"
ME_L
\n",
"
6
\n",
"
ACH
\n",
"
\n",
" \n",
"
\n",
"
3794615 rows × 5 columns
\n",
"
"
],
"text/plain": [
" pre_root_id post_root_id neuropil syn_count nt_type\n",
"0 720575940596125868 720575940608552405 LOP_R 5 ACH\n",
"1 720575940596125868 720575940611348834 LOP_R 7 ACH\n",
"2 720575940596125868 720575940613059993 LOP_R 5 GLUT\n",
"3 720575940596125868 720575940616986553 LOP_R 5 ACH\n",
"4 720575940596125868 720575940620124326 LOP_R 8 ACH\n",
"... ... ... ... ... ...\n",
"3794610 720575940660868737 720575940607206786 ME_L 9 GABA\n",
"3794611 720575940660868737 720575940608664873 ME_L 6 GABA\n",
"3794612 720575940660868737 720575940611462242 ME_L 6 GABA\n",
"3794613 720575940660868737 720575940622913063 ME_L 23 GABA\n",
"3794614 720575940660868737 720575940626553546 ME_L 6 ACH\n",
"\n",
"[3794615 rows x 5 columns]"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"connections = pd.read_csv('dat/flywire/connections.csv.gz')\n",
"connections"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Example: Find neurons of a specific cell type\n",
"LC10a is a cluster of higher-order visual neurons required by Drosophila males to track the female during courtship.\n",
"\n",
"We can find all LC10a neurons in the fly brain using boolean indexing into the classification table:"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
root_id
\n",
"
flow
\n",
"
super_class
\n",
"
class
\n",
"
sub_class
\n",
"
cell_type
\n",
"
hemibrain_type
\n",
"
hemilineage
\n",
"
side
\n",
"
nerve
\n",
"
\n",
" \n",
" \n",
"
\n",
"
3035
\n",
"
720575940620720112
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
3691
\n",
"
720575940638285109
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
3737
\n",
"
720575940614430111
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
4456
\n",
"
720575940623082237
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
right
\n",
"
NaN
\n",
"
\n",
"
\n",
"
4544
\n",
"
720575940623868853
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
125773
\n",
"
720575940631195217
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
126409
\n",
"
720575940631982929
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
126528
\n",
"
720575940631983185
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
126843
\n",
"
720575940627265223
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
"
\n",
"
127467
\n",
"
720575940610227162
\n",
"
intrinsic
\n",
"
visual_projection
\n",
"
NaN
\n",
"
NaN
\n",
"
LC10a
\n",
"
LC10
\n",
"
VPNd2
\n",
"
left
\n",
"
NaN
\n",
"
\n",
" \n",
"
\n",
"
227 rows × 10 columns
\n",
"
"
],
"text/plain": [
" root_id flow super_class class sub_class \\\n",
"3035 720575940620720112 intrinsic visual_projection NaN NaN \n",
"3691 720575940638285109 intrinsic visual_projection NaN NaN \n",
"3737 720575940614430111 intrinsic visual_projection NaN NaN \n",
"4456 720575940623082237 intrinsic visual_projection NaN NaN \n",
"4544 720575940623868853 intrinsic visual_projection NaN NaN \n",
"... ... ... ... ... ... \n",
"125773 720575940631195217 intrinsic visual_projection NaN NaN \n",
"126409 720575940631982929 intrinsic visual_projection NaN NaN \n",
"126528 720575940631983185 intrinsic visual_projection NaN NaN \n",
"126843 720575940627265223 intrinsic visual_projection NaN NaN \n",
"127467 720575940610227162 intrinsic visual_projection NaN NaN \n",
"\n",
" cell_type hemibrain_type hemilineage side nerve \n",
"3035 LC10a LC10 VPNd2 right NaN \n",
"3691 LC10a LC10 VPNd2 left NaN \n",
"3737 LC10a LC10 VPNd2 right NaN \n",
"4456 LC10a LC10 VPNd2 right NaN \n",
"4544 LC10a LC10 VPNd2 left NaN \n",
"... ... ... ... ... ... \n",
"125773 LC10a LC10 VPNd2 left NaN \n",
"126409 LC10a LC10 VPNd2 left NaN \n",
"126528 LC10a LC10 VPNd2 left NaN \n",
"126843 LC10a LC10 VPNd2 left NaN \n",
"127467 LC10a LC10 VPNd2 left NaN \n",
"\n",
"[227 rows x 10 columns]"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"LC10a_neurons = classification[classification['cell_type']=='LC10a']\n",
"LC10a_neurons"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Example: Find all postsynaptic partners of a given neuron"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"720575940620720112\n"
]
},
{
"data": {
"text/html": [
"